package ru.averta.notes.service.security.login;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import ru.averta.notes.dao.UserDao;
import ru.averta.notes.domain.User;

import java.util.ArrayList;
import java.util.List;

@Transactional(readOnly = true)
public class MyUserDetailsService implements UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(MyUserDetailsService.class);
    
    @Autowired
    private UserDao userDao;

    public UserDetails loadUserByUsername(String userMail)
            throws UsernameNotFoundException, DataAccessException {

        try {
            logger.debug("Ищем пользователя с логином {}", userMail);

            User user = userDao.findUserByMail(userMail);
            if (user == null) {
                logger.debug("Пользователь с логином {} не найден", userMail);
                throw new UsernameNotFoundException("logged user " + userMail + " not found");
            }

            logger.debug("Пользователь {} успешно найден", userMail);

            return new SecurityUser(user, getUserAuthorities(user));
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw e;
        }
    }

    private List<GrantedAuthority> getUserAuthorities(User user) {
        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();

        grandAuthority(user, authList, "ROLE_USER");
        if (user.isAdmin()) {
            grandAuthority(user, authList, "ROLE_ADMIN");
        }
        return authList;
    }

    private static void grandAuthority(User user, List<GrantedAuthority> authList, String authority) {
        logger.debug("Предоставляем пользователю {} роль {}", new String[]{user.getMail(), authority});
        authList.add(new GrantedAuthorityImpl(authority));
    }
}
